代码的坏味道

本文是重构 读书笔记第二篇

读完本文你会大概清楚重构开始和停止的时机以及重构机制如何运作。

重构一般是靠经验丰富者的直觉,本章也只是给出一些迹象来表明这里有一个可以用重构解决的问题。

重复代码

IDEA15新增了一个非常好的功能,就是遇到重复代码,IDE会用标记提醒你重复的代码段并可以跳转到重复代码。

常见的重复代码情况:

  • 同一个的类的两个函数含有相同的代码

  • 两个互为兄弟的子类内含相同表达式

  • 两个不相关的类出现重复代码

    对于第一种情况,需要使用Extract Method, 提炼出重复代码,然后让两个函数调用提炼出来的代码。

    对于第二种情况,可以将重复代码提炼出来后放入超类中。

    对于第三种情况,需要使用Extract Class , 将重复代码提炼到一独立类中,然后在另一个类中使用这个新类。

过长函数

拥有短函数的对象会获得比较好,比较长。

程序员使用短函数的忧虑 :

  • 在早前,子程序调用需要额外开销,现代的OO语言已经几乎完全免除了进程内的函数调用开销。

  • 短函数影响阅读。阅读时遇到函数确实需要跳转上下文去理解子程序做了什么,这一点,我们可以通过给函数起个好名字,这样代码阅读者只要通过名字去了解函数的作用,而不必去看其中写了什么,当然当阅读者需要去查看子程序是怎么做到的另外。

    如何确定提炼哪一段代码

  • 寻找注释

    如果代码前方有一行注释表示如下代码段的作用,此时就可以提炼这段代码,并在注释的基础上给这段函数命名。

  • 条件表达式和循环

    将条件表达式内提炼到方法。注.p238

    将循环和其内的代码提炼到一个独立函数中

过大的类

利用单个类做太多的事情,内存往往就会出现过多的实例变量。这时也就会有重复代码的情况出现。

过长参数列表

利用对象解决。

发散式变化 Divergent Change

一个类受多种变化的影响

如果某个类经常因为不同的原因在不同的方向上变化,就应该警惕到去找出某特定原因而造成的所有变化。然后运用Extract Class将他们提炼到另一个类中。

散弹式变化 shotgun surgery

一个变化引发多个类相应修改

此时需要将一系列相关行为都放进同一个类。

依赖情节 feature envy

面向对象的全部要点在于: 这是一种“将数据和对数据的操作行为包装子在一起”的技术

如果某个函数计算某个值而从另一个对象那里调用几乎大半的取值函数,则此时需要考虑迁移函数到另一个地方。

数据泥团 Data Clumps

如果多个数据项经常出现在一起,则应该讲他们提炼到一个对象中。

Switch Statements

面向对象的一个最明显特征就是: 少用switch语句.

多态可以带来优雅的解决办法。

冗余类

你所创建的每个类,都得有人去理解它,维护它,这些工作都是要花钱的,如果一个类的所得不值其身价,它应该消失。

夸夸其谈未来性 Speculate generality

删掉没有用的类或变量。

迷惑的临时变量 templorary field

中间人 middle man

防止过度封装,过多的“不干实事”的函数。

过多的注释

当你感觉要写注释时,请先尝试重构,试着让所有注释都显得多余

注释的作用:

  • 你不知道改干什么的时候
  • 记述将来的打算
  • 标记你并无十足把握的区域
  • 为什么做xx事